package network;

import com.cedarsoftware.util.io.JsonWriter;
import server.Server;
import java.io.*;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import packet.CommandRequest;

/**
 * Watches queue and sends packets over the network
 * @author Joel Garboden
 */
public class Q2NetRunnable implements Runnable
{
  Server loggingServer;

  private String identifier;
  private boolean active = true;

  private JsonWriter jsonOut;

  private PriorityBlockingQueue<CommandRequest> outQ;

  /**
   * Constructor
   * @param serverOut outgoing network stream
   * @param outQ outgoing network queue
   */
  public Q2NetRunnable(int ID, JsonWriter serverOut, PriorityBlockingQueue<CommandRequest> outQ)
  {
    if (ID < 0)
    {
      identifier = "a lobby client";
    }
    else
    {
      identifier = "client " + ID;
    }
    
    jsonOut = serverOut;
    
    this.outQ = outQ;
  }
  
  /**
   * Constructor
   * @param identifier player name
   * @param serverOut outgoing network stream
   * @param outQ outgoing network queue
   */
  public Q2NetRunnable(String identifier, JsonWriter serverOut, PriorityBlockingQueue<CommandRequest> outQ)
  {
    this.identifier = identifier;
    jsonOut = serverOut;
    this.outQ = outQ;
  }  

  /**
   * Mutator
   * @param ID player number ID
   */
  public void setName(String name)
  {
    identifier = name;
  }

  /**
   * Accessor
   * @return player number ID
   */
  public String getName()
  {
    return identifier;
  }

  /**
   * Enables logging to server
   * @param server logging to be dumped to
   */
  public void enableLogging(Server server)
  {
    loggingServer = server;
  }

  /**
   * Mutator
   * @param active activity state
   */
  public void setActive(boolean active)
  {
    this.active = active;
  }

  /**
   * Accessor
   * @return activity state
   */
  public boolean isActive()
  {
    return active;
  }

  /**
   * Continuously watches the outgoing queue, <br/>
   * and sends queued packets over the network
   */
  @Override
  public void run()
  {
    CommandRequest obj;
    try
    {
      try
      {
        while(active)
        {
          obj = (CommandRequest)outQ.take();
          //obj.setID(ID);
          if(jsonOut == null)
          {
            active = false;
            break;
          }
          
          jsonOut.write(obj);
          if(loggingServer != null)
            loggingServer.postLogMsg("Sent to " + identifier + " " + obj.toString());
          else
            System.out.println("Sent to " + identifier + " " + obj.toString());
        }
      }
      catch (IOException e)
      {
        Logger.getLogger(Q2NetRunnable.class.getName()).log(Level.SEVERE, "Q2Net runnable inner", e);
        active = false;
      }
    }
    catch(Throwable e)
    {
      Logger.getLogger(Q2NetRunnable.class.getName()).log(Level.SEVERE, "Q2Net runnable outer", e);
    }
  }
}
